package com.bkck.sharkblockade.highscores;

import java.util.Calendar;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class ScoresDB {
  static SQLiteOpenHelper scoresDbHelper;

  public ScoresDB(Context context) {
    scoresDbHelper = new ScoresDictionaryOpenHelper(context);
  }

  public SQLiteOpenHelper getOpenHelper() {
    return scoresDbHelper;
  }

  /**
   * Adds a score to the database.
   * 
   * @param name The user's name.
   * @param points The points scored.
   * @param timestamp The timestamp of the score.
   */
  public void addScoreToDB(String name, long points, int level) {
    if (name == null) {
      name = "User";
    }
    SQLiteDatabase db = null;
    long oldLowestScore = getLevelLowestScore(level);
    ContentValues cv = new ContentValues();
    cv.put("Name", name);
    cv.put("Points", points);
    cv.put("Date", (new Date()).getTime());
    cv.put("Level", level);
    // limit to 15 scores at most.
    if (getScoresForLevel(level).size() >= 15) {
      db = scoresDbHelper.getWritableDatabase();
      if (points >= oldLowestScore) {
        String[] whereArgs = { String.valueOf(oldLowestScore) };        
        db.delete("Scores", "Points= ?", whereArgs);
        db.insert("Scores", "Name", cv);
      }
    }
    else {
      db = scoresDbHelper.getWritableDatabase();
      db.insert("Scores", "Name", cv);
    }
    db.close();
  }

  /**
   * Returns the lowest score in the level given.
   * 
   * @param level The level.
   * @return The lowest score in the level given.
   */
  public Long getLevelLowestScore(int levelToFetch) {
    Long points = 0L;
    SQLiteDatabase db = scoresDbHelper.getReadableDatabase();
    Cursor cursor = db.query("Scores", null, null, null, null, null, "Points ASC");

    while (cursor.moveToNext()) {
      int level = cursor.getInt(cursor.getColumnIndex("Level"));

      // Only add to list if the score matches the level we are searching for.
      if (level == levelToFetch) {

        // String name = cursor.getString(cursor.getColumnIndex("Name"));
        points = cursor.getLong(cursor.getColumnIndex("Points"));
        // long timestamp = cursor.getLong(cursor.getColumnIndex("Date"));

        // Score score = new Score(name, points, timestamp, level);
        // list.add(score);
        cursor.close();
        db.close();
        return points;
      }
    }
    cursor.close();
    db.close();
    return points;
  }

  /**
   * Gets a list of all scores.
   * 
   * @return List containing all scores.
   */
  public List<Score> getAllScores() {
    List<Score> list = new LinkedList<Score>();
    SQLiteDatabase db = scoresDbHelper.getReadableDatabase();
    Cursor cursor = db.query("Scores", null, null, null, null, null, "Points DESC");

    while (cursor.moveToNext()) {
      String name = cursor.getString(cursor.getColumnIndex("Name"));
      long points = cursor.getLong(cursor.getColumnIndex("Points"));
      long timestamp = cursor.getLong(cursor.getColumnIndex("Date"));
      int level = cursor.getInt(cursor.getColumnIndex("Level"));

      Score score = new Score(name, points, timestamp, level);
      list.add(score);
    }
    cursor.close();
    db.close();
    return list;
  }

  public List<Score> getScoresForLevel(int levelToFetch) {
    List<Score> list = new LinkedList<Score>();
    SQLiteDatabase db = scoresDbHelper.getReadableDatabase();
    Cursor cursor = db.query("Scores", null, null, null, null, null, "Points DESC");

    while (cursor.moveToNext()) {
      int level = cursor.getInt(cursor.getColumnIndex("Level"));

      // Only add to list if the score matches the level we are searching for.
      if (level == levelToFetch) {

        String name = cursor.getString(cursor.getColumnIndex("Name"));
        long points = cursor.getLong(cursor.getColumnIndex("Points"));
        long timestamp = cursor.getLong(cursor.getColumnIndex("Date"));

        Score score = new Score(name, points, timestamp, level);
        list.add(score);
      }
    }
    cursor.close();
    db.close();
    return list;
  }

  /**
   * Formats list of scores.
   * 
   * @param list
   * @return
   */
  public String listToString(List<Score> list) {

    int index = 1;
    String indexString;
    String returnString = "";
    String displayName;
    String displayDate;
    int calendarValue;

    // Loop through scores and format
    for (Score score : list) {
      Calendar date = Calendar.getInstance();
      date.setTimeInMillis(score.getTimestamp());

      if (index < 10) {
        indexString = index + ". ";
      }
      else {
        indexString = index + ".";
      }

      // Add spaces if necessary to get fixed string length of 10
      displayName = score.getName();
      while (displayName.length() < 10) {
        displayName += " ";
      }

      calendarValue = date.get(Calendar.MONTH) + 1;
      if (calendarValue < 10) {
        displayDate = "0" + calendarValue + "/";
      }
      else {
        displayDate = calendarValue + "/";
      }

      calendarValue = date.get(Calendar.DAY_OF_MONTH);
      if (calendarValue < 10) {
        displayDate += "0" + calendarValue + "/";
      }
      else {
        displayDate += calendarValue + "/";
      }

      calendarValue = date.get(Calendar.YEAR) % 100;
      if (calendarValue < 10) {
        displayDate += "0" + calendarValue;
      }
      else {
        displayDate += calendarValue;
      }

      returnString +=
          indexString + displayName + "\t" + displayDate + "\t\t" + score.getScore() + "\n";
      index++;
    }
    return returnString;
  }

  public static void deleteAll() {
    SQLiteDatabase db = scoresDbHelper.getWritableDatabase();
    db.delete("Scores", null, null);
    db.close();
  }

}

